home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 255_01 / gpball.asm < prev    next >
Encoding:
Assembly Source File  |  1988-03-28  |  18.0 KB  |  518 lines

  1.           page   80,132
  2.           page
  3. ;
  4. ;       EGA Graphic Primitive for Turbo Pascal 3.01A, Version 01MAR86.
  5. ;       (C) 1986 by Kent Cedola, 2015 Meadow Lake Ct., Norfolk, VA, 23518
  6. ;
  7. ;       The algorithm for drawing a circle (below) was from an article in
  8. ;       Dr. Dobb's Journal, December 1983, pp. 19 by Michael T. Enright.
  9. ;
  10. ;       I converted it from BASIC source (from above) to assembler for high
  11. ;       speed plotting and added color/shading fill and clipping code.
  12. ;
  13.  
  14. radius    equ    4
  15.  
  16. xcoor1    equ    -2                    ; X coordinate (left half)
  17. xcoor2    equ    -4                    ; X coordinate (right half)
  18. ycoor1    equ    -6                    ; Location of Y graphic row, contains
  19. ycoor2    equ    -8                    ;   ... row byte offset.
  20.  
  21. xc        equ    -10
  22. yc        equ    -12
  23.  
  24. xd        equ    -14                   ; Long integer (32 bits)
  25. yd        equ    -18                   ; Long integer (32 bits)
  26. zx        equ    -22                   ; Long integer (32 bits)
  27. zy        equ    -26                   ; Long integer (32 bits)
  28. tx        equ    -30                   ; Long integer (32 bits)
  29. ty        equ    -34                   ; Long integer (32 bits)
  30. tb        equ    -38                   ; Long integer (32 bits)
  31. er        equ    -42                   ; Long integer (32 bits)
  32. atx       equ    -46                   ; Long integer (32 bits)
  33. aty       equ    -50                   ; Long integer (32 bits)
  34. atb       equ    -54                   ; Long integer (32 bits)
  35.  
  36. xf1       equ    -58
  37. xf2       equ    -60
  38. yf1       equ    -62
  39. yf2       equ    -64
  40.  
  41. needed    equ    68                    ; Amount of temporary space needed
  42.  
  43. dgroup    group  _data
  44.  
  45. _data     segment word public 'data'
  46.           assume ds:dgroup
  47.  
  48.           extrn  _gdtype:byte
  49.           extrn  _gdmaxcol:word,_gdmaxrow:word
  50.           extrn  _gdcolor:byte,_gdmerge:byte,_gdaspc1:word,_gdaspc2:word
  51.           extrn  _gdcur_x:word,_gdcur_y:word
  52.           extrn  _gdwd_x1:word,_gdwd_x2:word,_gdwd_x3:word
  53.           extrn  _gdwd_y1:word,_gdwd_y2:word,_gdwd_y3:word
  54.           extrn  _gdvw_x1:word,_gdvw_x2:word,_gdvw_x3:word
  55.           extrn  _gdvw_y1:word,_gdvw_y2:word,_gdvw_y3:word
  56.           extrn  _gdshade:word
  57.           extrn  _gdc_flg:byte,_gds_flg:byte,_gdw_flg:byte
  58.  
  59. _data     ends
  60.  
  61. _text     segment byte public 'code'
  62.  
  63.           assume cs:_text,ds:dgroup
  64.           public _gpball
  65. _gpball   proc   near
  66.  
  67.           push   bp
  68.           mov    bp,sp
  69.           sub    sp,needed             ; Reserve space for temp. variables
  70.  
  71.           push   si
  72.           push   di
  73.  
  74.           mov    _GDC_FLG,2            ; Set clipping flag
  75.  
  76. ;    Compute AE = R (save in BX for later)
  77.  
  78.           mov    ax,[bp+radius]        ; Load user specified radius
  79.           or     ax,ax                 ; If radius is zero, make it 1
  80.           jnz    notzero               ;
  81.           inc    ax                    ;
  82. notzero:
  83.           mov    bx,ax                 ; Copy to BX (AX used later)
  84.           mov    ax,_GDCUR_X
  85.           sub    ax,bx
  86.           cmp    ax,_GDVW_X2
  87.           jbe    next1
  88.           jmp    theend
  89. next1:
  90.           mov    [bp+xc],ax
  91.           add    ax,bx
  92.           add    ax,bx
  93.           cmp    ax,_GDVW_X1
  94.           jae    next2
  95.           jmp    theend
  96. next2:
  97.  
  98. ;    Compute BE = (R * _GDASPC1 / _GDASPC2) (save in DX for later)
  99.  
  100.           mov    ax,bx                 ; Start with R (AE above)
  101.           mul    _GDASPC1           ; Compute the real Y radius from the
  102.           div    _GDASPC2           ;      the defined screen aspects
  103.           mov    dx,ax                 ; Copy to DX (temp save area)
  104.  
  105. ;    Compute the Y coordinate graphic row offset.
  106.  
  107.           mov    cx,_GDCUR_Y           ; Compute the upper and lower row for
  108.           sub    cx,ax                 ;   line clipping logic
  109.           cmp    cx,_GDVW_Y2           ;
  110.           jbe    next3
  111.           jmp    theend
  112. next3:
  113.           mov    [bp+yc],cx
  114.           mov    [bp+yf1],cx           ;   ...
  115.           add    cx,ax                 ;   ...
  116.           add    cx,ax                 ;   ...
  117.           cmp    cx,_GDVW_Y1
  118.           jae    next4
  119.           jmp    theend
  120. next4:
  121.           mov    [bp+yf2],cx           ;   ...
  122.  
  123.           mov    _GDC_FLG,0            ; Clear clipping flag
  124.  
  125.           shl    ax,1                  ; Compute the graphic segment offset
  126.           shl    ax,1                  ;   for the Y radius length
  127.           add    ax,dx                 ;   ...
  128.           mov    si,ax                 ; Copy to SI (temp save area)
  129.  
  130.           mov    ax,_GDCUR_Y           ; Compute the graphic segment offset
  131.           shl    ax,1                  ;   for the current row
  132.           shl    ax,1                  ;   ... = A000 + (80 * Y) / 16;
  133.           add    ax,_GDCUR_Y           ;   ...
  134.           add    ax,0A000h             ;   ...
  135.           sub    ax,si                 ; Init the top and bottow y coordinates
  136.           mov    [bp+ycoor1],ax        ;   ...
  137.           add    ax,si                 ;   ...
  138.           add    ax,si                 ;   ...
  139.           mov    [bp+ycoor2],ax        ;   ...
  140.  
  141. ;    Compute the X coordinate graphic bit offset.
  142.  
  143.           mov    ax,_GDCUR_X           ; Compute the column byte offset
  144.           mov    [bp+xf1],ax           ; Save the left and right column numbers
  145.           mov    [bp+xf2],ax           ;   for clipping logic
  146.  
  147. ;    Compute XD = BE * BE
  148.  
  149.           mov    cx,dx                 ; Save BE for later (in CX)
  150.           mov    ax,dx                 ; Must use AX for multiply
  151.           mul    dx                    ; BE * BE (AX * DX)
  152.           mov    [bp+xd],ax            ; Save XD
  153.           mov    [bp+xd-2],dx          ;   ...
  154.  
  155. ;    Compute DX = 2 * BE * BE (or XD * 2)
  156.  
  157.           shl    ax,1                  ; Long shift left for multiply
  158.           rcl    dx,1                  ;   ...
  159.           mov    [bp+zx],ax            ; Save DX
  160.           mov    [bp+zx-2],dx          ;   ...
  161.  
  162. ;    Compute DY = 2 * AE * AE
  163.  
  164.           mov    ax,bx                 ; Move current AE to AX
  165.           mul    bx                    ;   ... (AE * AE)
  166.           push   dx                    ; Save the value (AE * AE) for later
  167.           push   ax                    ;   ...
  168.           shl    ax,1                  ; Compute AE * AE * 2 (shift left)
  169.           rcl    dx,1                  ;   ...
  170.           mov    [bp+zy],ax            ; Save DY
  171.           mov    [bp+zy-2],dx          ;   ...
  172.  
  173. ;    Compute YD = (2 * BE - 1) * AE * AE
  174.  
  175.           pop    ax
  176.           shl    cx,1                  ; Compute BE * 2
  177.           dec    cx                    ; Compute BE * 2 - 1
  178.           mul    cx                    ; Compute (BE * 2 - 1) * AE
  179.           mov    [bp+yd],ax            ; Save what we have so far
  180.           mov    [bp+yd-2],dx          ;   ...
  181.           pop    ax                    ; Compute (BE * 2 - 1) * AE * AE
  182.           mul    cx                    ;   ...
  183.           add    [bp+yd-2],ax          ;   ...
  184.  
  185. ;    Compute ER = 0
  186.  
  187.           xor    ax,ax                 ; Clear AX to clear ER
  188.           mov    [bp+er],ax            ;   ...
  189.           mov    [bp+er-2],ax          ;   ...
  190.  
  191. ;    Setup the EGA to perform graphics
  192.  
  193.           mov    dx,03CEh              ; Load EGA graphic controller port addr.
  194.           mov    ah,_GDMERGE           ; Load current merge setting
  195.           mov    al,3                  ; Merge register is number three
  196.           out    dx,ax                 ; Set the EGA's merge register
  197.           mov    ax,0205h              ; Load write mode number two
  198.           out    dx,ax                 ; Set the EGA's mode register
  199.           mov    al,8                  ; Load the mask register number
  200.           out    dx,al                 ; Just postion EGA's controller to it
  201.  
  202.           call   plotpnts              ; Plot the first set of points
  203.  
  204. next_x:
  205.           mov    cx,-1
  206.  
  207.           mov    ax,[bp+er]            ; Compute TX = ER + XD
  208.           mov    dx,[bp+er-2]          ;   ...
  209.           add    ax,[bp+xd]            ;   ...
  210.           adc    dx,[bp+xd-2]          ;   ...
  211.           mov    [bp+tx],ax            ;   ...
  212.           mov    [bp+tx-2],dx          ;   ...
  213.           jns    abs_tx                ; Compute ATX = abs(TX), if needed
  214.           xor    ax,cx
  215.           xor    dx,cx
  216.           inc    ax
  217.           jnc    abs_tx
  218.           inc    dx
  219. abs_tx:
  220.           mov    [bp+atx],ax           ;   ...
  221.           mov    [bp+atx-2],dx         ;   ...
  222.  
  223.           mov    ax,[bp+er]            ; Compute TY = ER - YD
  224.           mov    dx,[bp+er-2]          ;   ...
  225.           sub    ax,[bp+yd]            ;   ...
  226.           sbb    dx,[bp+yd-2]          ;   ...
  227.           mov    [bp+ty],ax            ;   ...
  228.           mov    [bp+ty-2],dx          ;   ...
  229.           jns    abs_ty                ; Compute ATY = abs(TY), if needed
  230.           xor    ax,cx                 ;   ...
  231.           xor    dx,cx                 ;   ...
  232.           inc    ax                    ;   ...
  233.           jnc    abs_ty                ;   ...
  234.           inc    dx                    ;   ...
  235. abs_ty:
  236.           mov    [bp+aty],ax           ;   ...
  237.           mov    [bp+aty-2],dx         ;   ...
  238.  
  239.           mov    ax,[bp+tx]            ; Compute TB = ER + XD - YD
  240.           mov    dx,[bp+tx-2]          ;   ... (or TB = TX - YD)
  241.           sub    ax,[bp+yd]            ;   ...
  242.           sbb    dx,[bp+yd-2]          ;   ...
  243.           mov    [bp+tb],ax            ;   ...
  244.           mov    [bp+tb-2],dx          ;   ...
  245.           jns    abs_tb                ; Compute ATB = abs(TB), if needed
  246.           xor    ax,cx                 ;   ...
  247.           xor    dx,cx                 ;   ...
  248.           inc    ax                    ;   ...
  249.           jnc    abs_tb                ;   ...
  250.           inc    dx                    ;   ...
  251. abs_tb:
  252.           mov    [bp+atb],ax           ;   ...
  253.           mov    [bp+atb-2],dx         ;   ...
  254.  
  255. cond1:
  256.           mov    ax,[bp+atx]           ; Load absolute value of TX
  257.           mov    dx,[bp+atx-2]         ;   ...
  258.           cmp    dx,[bp+aty-2]         ; if (abs(TX) < abs(TY)
  259.           ja     cond2                 ;   ...
  260.           jb     cond1a                ;   ...
  261.           cmp    ax,[bp+aty]           ;   ...
  262.           jae    cond2                 ;   ...
  263. cond1a:
  264.           cmp    dx,[bp+atb-2]         ; and (abs(TX) < abs(TB))
  265.           ja     cond2                 ;   ...
  266.           jb     cond1b                ;   ...
  267.           cmp    ax,[bp+atb]           ;   ...
  268.           jae    cond2                 ;   ...
  269. cond1b:
  270.  
  271. ;    Compute XF1 = XF1 - 1
  272.  
  273.           dec    word ptr [bp+xf1]
  274.  
  275. ;    Compute XF2 = XF2 + 1
  276.  
  277.           inc    word ptr [bp+xf2]
  278.  
  279.           mov    ax,[bp+tx]            ; ER = TX
  280.           mov    dx,[bp+tx-2]          ;   ...
  281.           mov    [bp+er],ax            ;   ...
  282.           mov    [bp+er-2],dx          ;   ...
  283.           mov    ax,[bp+zx]            ; XD = XD + DX
  284.           mov    dx,[bp+zx-2]          ;   ...
  285.           add    [bp+xd],ax            ;   ...
  286.           adc    [bp+xd-2],dx          ;   ...
  287.  
  288.           jmp    until
  289.  
  290. cond2:
  291.           mov    ax,[bp+aty]           ; Load absolute value of TY
  292.           mov    dx,[bp+aty-2]         ;   ...
  293.           cmp    dx,[bp+atx-2]         ; if (abs(TY) < abs(TX)
  294.           ja     cond3                 ;   ...
  295.           jb     cond2a                ;   ...
  296.           cmp    ax,[bp+atx]           ;   ...
  297.           jae    cond3                 ;   ...
  298. cond2a:
  299.           cmp    dx,[bp+atb-2]         ; and (abs(TY) < abs(TB))
  300.           ja     cond3                 ;   ...
  301.           jb     cond2b                ;   ...
  302.           cmp    ax,[bp+atb]           ;   ...
  303.           jae    cond3                 ;   ...
  304. cond2b:
  305.  
  306. ;    Compute YF1 = YF1 - 1
  307.  
  308.           add    word ptr [bp+ycoor1],5
  309.           inc    word ptr [bp+yf1]
  310.  
  311. ;    Compute YF2 = YF2 + 1
  312.  
  313.           sub    word ptr [bp+ycoor2],5
  314.           dec    word ptr [bp+yf2]
  315.  
  316.           mov    ax,[bp+ty]            ; ER = TY
  317.           mov    dx,[bp+ty-2]          ;   ...
  318.           mov    [bp+er],ax            ;   ...
  319.           mov    [bp+er-2],dx          ;   ...
  320.  
  321.           mov    ax,[bp+zy]            ; YD = YD - DY
  322.           mov    dx,[bp+zy-2]          ;   ...
  323.           sub    [bp+yd],ax            ;   ...
  324.           sbb    [bp+yd-2],dx          ;   ...
  325.  
  326.           jmp    until
  327.  
  328. cond3:
  329.  
  330. ;    Compute XF1 = XF1 - 1
  331.  
  332.           dec    word ptr [bp+xf1]
  333.  
  334. ;    Compute XF2 = XF2 + 1
  335.  
  336.           inc    word ptr [bp+xf2]
  337.  
  338. ;    Compute YF1 = YF1 + 1
  339.  
  340.           add    word ptr [bp+ycoor1],5
  341.           inc    word ptr [bp+yf1]
  342.  
  343. ;    Compute YF2 = YF2 - 1
  344.  
  345.           sub    word ptr [bp+ycoor2],5
  346.           dec    word ptr [bp+yf2]
  347.  
  348.           mov    ax,[bp+tb]            ; ER = TB
  349.           mov    dx,[bp+tb-2]          ;   ...
  350.           mov    [bp+er],ax            ;   ...
  351.           mov    [bp+er-2],dx          ;   ...
  352.  
  353.           mov    ax,[bp+zx]            ; XD = XD + DX
  354.           mov    dx,[bp+zx-2]          ;   ...
  355.           add    [bp+xd],ax            ;   ...
  356.           adc    [bp+xd-2],dx          ;   ...
  357.  
  358.           mov    ax,[bp+zy]            ; YD = YD - DY
  359.           mov    dx,[bp+zy-2]          ;   ...
  360.           sub    [bp+yd],ax            ;   ...
  361.           sbb    [bp+yd-2],dx          ;   ...
  362.  
  363. until:
  364.           call   plotpnts              ; Plot the next set of points
  365.  
  366.           mov    ax,[bp+ycoor1]        ; When the two y coordinates are equal
  367.           cmp    ax,[bp+ycoor2]        ;   ... we are done.
  368.           je     done                  ;   ... (all done condition)
  369.           jmp    next_x                ;   ... (do the next row condition)
  370. done:
  371.           mov    dx,03CFh
  372.           mov    al,0FFh               ; Reset EGA back to standard mode
  373.           out    dx,al                 ;   ...
  374.           dec    dx                    ;   ...
  375.           mov    ax,0005h              ;   ...
  376.           out    dx,ax                 ;   ...
  377.           mov    al,03h                ;   ...
  378.           out    dx,ax                 ;   ...
  379.  
  380.           jmp    theend                ; Restore the callers parameter frame
  381.  
  382. plotpnts:
  383.           mov    ax,[bp+xf1]           ; Load left x coordinate
  384.           mov    di,_GDVW_X2           ; Load X2 coordinate of viewport (speed)
  385.           cmp    ax,di                 ; Are we out of the viewport?
  386.           ja     plotret               ;   Yes, skip this plot
  387.           mov    cx,[bp+xf2]           ; Load right x coordinate
  388.           mov    si,_GDVW_X1           ; Load X1 coordinate of viewport (speed)
  389.           cmp    cx,si                 ; Are we out of the viewport?
  390.           jb     plotret               ;   Yes, skip this plot
  391.           cmp    ax,si                 ; Clip x1 to stay in viewport
  392.           jae    plot01                ;   Already in the viewport, continue
  393.           mov    ax,si                 ;   Lets clip it
  394. plot01:
  395.           cmp    cx,di                 ; Clip x2 to stay in viewport
  396.           jbe    plot02                ;   Already in the viewport, continue
  397.           mov    cx,di                 ;   Lets clip it
  398. plot02:
  399.           sub    cx,ax                 ; Compute delta X + 1
  400.           inc    cx                    ;   ...
  401.           push   ax                    ; Save starting x coordinate for later
  402.           push   cx                    ; Save counter for later
  403.  
  404.           mov    cx,ax                 ; Compute starting bit
  405.           shr    ax,1                  ;
  406.           shr    ax,1                  ;
  407.           shr    ax,1                  ;
  408.           mov    di,ax                 ;
  409.           and    cl,7                  ;
  410.           mov    al,080h               ;
  411.           ror    al,cl                 ;
  412.           mov    dx,03CFh              ;
  413.  
  414.           pop    cx                    ; Restore counter (width of line)
  415.           pop    bx
  416.  
  417.           mov    si,[bp+yf1]
  418.           cmp    si,_GDVW_Y1
  419.           jb     plot03
  420.           cmp    si,_GDVW_Y2
  421.           ja     plot03
  422.           mov    es,[bp+ycoor1]
  423.           push   ax
  424.           push   bx
  425.           push   cx
  426.           push   di
  427.           call   plotline
  428.           pop    di
  429.           pop    cx
  430.           pop    bx
  431.           pop    ax
  432. plot03:
  433.           mov    si,[bp+yf2]
  434.           cmp    si,_GDVW_Y1
  435.           jb     plotret
  436.           cmp    si,_GDVW_Y2
  437.           ja     plotret
  438.           mov    es,[bp+ycoor2]
  439.           call   plotline
  440.  
  441. plotret:
  442.           ret
  443.  
  444. plotline:
  445.           cmp    _GDS_FLG,0
  446.           jne    shading
  447.  
  448. color:
  449.           mov    ah,_GDCOLOR
  450. color01:
  451.           out    dx,al
  452.           mov    bh,es:[di]
  453.           mov    es:[di],ah
  454.           ror    al,1
  455.           jnc    color04
  456. color02:
  457.           inc    di
  458.           cmp    cx,8
  459.           jb     color04
  460.           mov    al,0FFh
  461.           out    dx,al
  462. color03:
  463.           mov    es:[di],ah
  464.           inc    di
  465.           sub    cx,8
  466.           cmp    cx,8
  467.           jae    color03
  468.           mov    al,080h
  469.           inc    cx
  470. color04:
  471.           loop   color01
  472.           ret
  473.  
  474. ;         al = bit
  475. ;         bx = starting offset
  476. ;         cx = width
  477. ;         dx = port
  478. ;         di = byte
  479. ;         es = segment
  480.  
  481. shading:
  482.           mov    si,_GDSHADE
  483.           mov    bx,[si]
  484.           inc    si
  485.           inc    si
  486.           push   cx
  487.           xor    bh,bh
  488.           mov    cx,bx
  489.           jmp    short shade02
  490. shade01:
  491.           push   cx
  492.           mov    cx,bx
  493.           sub    si,bx
  494. shade02:
  495.           out    dx,al
  496.           mov    ah,es:[di]
  497.           mov    ah,[si]
  498.           mov    es:[di],ah
  499.           ror    al,1
  500.           adc    di,0
  501.           inc    si
  502.           loop   shade02
  503.           pop    cx
  504.           loop   shade01
  505.           ret
  506.  
  507. theend:
  508.           pop    di
  509.           pop    si
  510.  
  511.           mov    sp,bp                 ; Restore the stack
  512.           pop    bp
  513.           ret
  514. _gpball   endp
  515.  
  516. _text     ends
  517.           end
  518.